﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using HeritageAcademy.Models.DataModels;
using HeritageAcademy.Models.Loaders;
using HeritageAcademy.Models.ViewModels;
using HeritageAcademy.Shared.Languages;

namespace HeritageAcademy.Library.Controls
{
    /// <summary>
    /// Course details view class.
    /// </summary>
    public partial class DetailsView
    {
        #region Parameters

        private static readonly double ONE_PARAGRAPH_DURATION =
            Convert.ToDouble(Shared.Properties.Resources.Course_ParagraphDuration);

        private UsersConfigLoader _usersConfigLoader;
        private CoursesConfigLoader _coursesConfigLoader;
        private CourseViewModel cvm;
        private readonly Russian _russian;
        private readonly Shared.Duration _duration;

        #endregion

        #region Ctor

        public DetailsView()
        {
            InitializeComponent();

            _russian = new Russian();
            _duration = new Shared.Duration();

            btnTest.Click += btnTest_Click;
            btnStart.Click += btnStart_Click;

            tbDurationBottomCaption.Text = String.Format("из расчета {0} минут на параграф", ONE_PARAGRAPH_DURATION);
            DataContextChanged += DetailsView_DataContextChanged;
        }

        #endregion

        #region Event Handlers

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            Navigator.Current.ShowCourse(cvm);

            // ADD INFO ABOUT START TO COURSE CONFIG FILE.
            var currentUserId = _usersConfigLoader.ActiveUser.Id;
            var currentCourseId = cvm.Model.Identifier;

            //if ( isStarted(_coursesConfigLoader, currentCourseId, currentUserId) ) return;

            var smart = new Student {Id = currentUserId, Progress = "0.12"}; // TODO: realize Progress tracking
            var courseData = new CourseData();

            var existsCourse = false;
            var existsStudent = false;
            
            // search the existing record
            foreach ( var course in _coursesConfigLoader.Model.CourseData.Where(course => (course.Id == currentCourseId & course.Level == nnsLevelSelector.CurrentValue.ToString())) )
            {
                existsCourse = true;
                foreach ( var student in course.Students.Where(student => student.Id == currentUserId) )
                    existsStudent = true;
                courseData = course;
            }

            if (!existsCourse)
            {
                courseData.Id = currentCourseId;
                courseData.Level = nnsLevelSelector.CurrentValue.ToString();
                courseData.Students.Add(smart);
                existsStudent = true;
                _coursesConfigLoader.Model.CourseData.Add(courseData);
            }

            if (!existsStudent)
            {
                courseData.Students.Add(smart);    
            }

            _coursesConfigLoader.Save();
        }

        private void btnTest_Click(object sender, RoutedEventArgs e)
        {
            var _cvm = (CourseViewModel) DataContext;
            CourseLoader.UnzipTests(_cvm.Model.Title);
            Navigator.Current.ShowTestBoard(_cvm);
        }

        private void DetailsView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            UpdateDetails();
        }

        private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
        {
            Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
            e.Handled = true;
        }

        #endregion

        #region Properties

        public string CourseTitle
        {
            set { tbCourseTitle.Text = value; }
        }

        public string CourseDescription
        {
            set { tbCourseDescription.Text = value; }
        }

        #endregion

        #region Private Methods
        
        private static bool isStarted(LoaderBase<CoursesData> data, string courseId, string courseLevel, string userId)
        {
            var started = false;
            foreach ( var course in from course in data.Model.CourseData
                                                where course.Id == courseId & course.Level == courseLevel
                                                from student in course.Students.Where(student => student.Id == userId)
                                                select course )
            {
                started = true;
            }
            return started;
        }

        private void ShowDuration(IDictionary<string, int> duration)
        {
            int w = duration["weeks"];
            int d = duration["days"];
            int h = duration["hours"];
            int m = duration["minutes"];

            if ( w != 0 )
            {
                tbW.Text = w.ToString();
                tbWCaption.Text = _russian.Grammar(Russian.Word.Week, w);
                tbW.Visibility = Visibility.Visible;
                tbWCaption.Visibility = Visibility.Visible;
            }
            else
            {
                tbW.Visibility = Visibility.Collapsed;
                tbWCaption.Visibility = Visibility.Collapsed;
            }

            if ( d != 0 )
            {
                tbD.Text = d.ToString();
                tbDCaption.Text = _russian.Grammar(Russian.Word.Day, d);
                tbD.Visibility = Visibility.Visible;
                tbDCaption.Visibility = Visibility.Visible;
            }
            else
            {
                tbD.Visibility = Visibility.Collapsed;
                tbDCaption.Visibility = Visibility.Collapsed;
            }

            if ( h != 0 )
            {
                tbH.Text = h.ToString();
                tbHCaption.Text = _russian.Grammar(Russian.Word.Hour, h);
                tbH.Visibility = Visibility.Visible;
                tbHCaption.Visibility = Visibility.Visible;
            }
            else
            {
                tbH.Visibility = Visibility.Collapsed;
                tbHCaption.Visibility = Visibility.Collapsed;
            }

            if ( m != 0 )
            {
                tbM.Text = m.ToString();
                tbMCaption.Text = _russian.Grammar(Russian.Word.Minute, m);
                tbM.Visibility = Visibility.Visible;
                tbMCaption.Visibility = Visibility.Visible;
            }
            else
            {
                tbM.Visibility = Visibility.Collapsed;
                tbMCaption.Visibility = Visibility.Collapsed;
            }
        }

        private void UpdateDetails()
        {
            cvm = (CourseViewModel) DataContext;
            _usersConfigLoader = new UsersConfigLoader(new Users());
            _coursesConfigLoader = new CoursesConfigLoader(new CoursesData());

            ShowDuration(_duration.Calculate(((CourseViewModel) DataContext).Model.ParagraphCount, ONE_PARAGRAPH_DURATION));
            //((BookViewModel)DataContext).Model.UserMetadata.LastReadLocation.ToString();
            // ((BookViewModel)DataContext).Model.UserMetadata.LastAccess.ToShortDateString()
            btnStart.Content = (isStarted(_coursesConfigLoader, cvm.Model.Identifier, "1", _usersConfigLoader.ActiveUser.Id )) ? "Продолжить" : "Начать"; // TODO: realize Level tracking
            var tc = (new TestWizardViewModel((CourseViewModel) DataContext)).TestCount; //TODO: Async
            if ( tc == -1 ) // no tests
            {
                tbTestsCounter.Visibility = Visibility.Collapsed;
                tbTestsCounterCaption.Visibility = Visibility.Collapsed;
                tbNoTests.Visibility = Visibility.Visible;
                btnTest.IsEnabled = false;
            }
            else
            {
                tbNoTests.Visibility = Visibility.Collapsed;
                tbTestsCounter.Text = tc.ToString();
                tbTestsCounterCaption.Text = _russian.Grammar(Russian.Word.Test, tc);
                tbTestsCounter.Visibility = Visibility.Visible;
                tbTestsCounterCaption.Visibility = Visibility.Visible;
                btnTest.IsEnabled = true;
            }

            nnsLevelSelector.MaxValue = 4;
            nnsLevelSelector.MinValue = 1;
        }

        #endregion
    }
}